import re
import tkinter
import tkinter.messagebox
from tkinter import filedialog
from openpyxl import Workbook
from openpyxl.styles import PatternFill, Alignment
import threading


def read_data(file):
    try:
        with open(file, 'r') as f:
            text = list(map(lambda x: re.sub(r'\n', '', x), f.readlines()))
    except:
        with open(file, 'r', encoding='utf8') as f:
            text = list(map(lambda x: re.sub(r'\n', '', x), f.readlines()))
    text = re.findall(r'VehNr;.*?Type;.*?t;.*?WorldX;.*?WorldY;.*?vMS;(.*)', ''.join(text), re.S)[0]
    text = re.sub(r'\n', '', text)
    text = re.sub(r'\s', '', text).split(';')
    while '' in text:
        text.remove('')
    text = list(map(eval, text))
    rows = len(text) // 6
    ls = []
    for i in range(rows):
        ls.append(text[6*i: 6*(i+1)])
    dic = dict()
    # 将vehnr字段按值分为n个列表，每个列表嵌套相关数组
    for i in ls:
        vehnr = i[0]
        if not vehnr in dic:
            dic[vehnr] = [i[2:]]
        else:
            dic[vehnr].append(i[2:])
    return rows, dic


def choose_data(dic):
    useful = []
    for i in dic:
        each_dic = dict()
        v_ls = list(map(lambda x: x[-1], dic[i]))
        m = len(v_ls)
        if m == 0:
            continue
        elif m == 1:
            if 0 in v_ls:
                each_dic['首次0'] = dic[i][0]
            continue
        if 0 in v_ls:
            index_left = v_ls.index(0)
            index_right = len(v_ls) - list(reversed(v_ls)).index(0) - 1
            each_dic['首次0'] = dic[i][index_left]
            each_dic['最后0'] = dic[i][index_right]
            try:
                each_dic['最后0邻'] = dic[i][index_right+1]
            except IndexError:
                pass
            try:
                each_dic['首次0邻'] = dic[i][index_left-1]
            except IndexError:
                pass
        useful.append([i, each_dic])
    return useful


# 车辆排队长度
def queue_length(td, ta, xp, v1, v2):
    return xp + (td - ta) / (1/v1 - 1/v2)


# 车速
def vel(x1, x2, t1, t2):
    return (x2 - x1) / (t2 - t1)


def new_t(ls):
    dic_135, dic_138 = {}, {}
    for each_ls in ls:
        data = each_ls[1]
        if data:
            try:
                arg1 = data['首次0邻']
                arg2 = data['首次0']
                arg3 = data['最后0']
                arg4 = data['最后0邻']
            except KeyError:
                continue
            t1 = arg1[0] + 2 * (arg1[1] - arg2[1]) / arg1[-1]
            t2 = arg4[0] - 2 * (arg3[1] - arg4[1]) / arg4[-1]
            each_ls[1]['t1’'] = t1
            each_ls[1]['t2‘'] = t2
            each_ls[1]['delta_t1'] = min(abs(t1%148), abs(148-t1%148))
            each_ls[1]['delta_t2'] = min(abs(t2%148), abs(148-t2%148))
            each_ls[1]['时间段1'] = '%d~%d' % (t1 // 148, t1 // 148 + 1)
            each_ls[1]['时间段2'] = '%d~%d' % (t2 // 148, t2 // 148 + 1)
            if int(arg2[2]) == 135:
                if not t2//148 in dic_135:
                    dic_135[int(t2//148)] = [[each_ls[0], arg2[1], t1, t2]]
                else:
                    dic_135[int(t2 // 148)].append([each_ls[0], arg2[1], t1, t2])
            else:
                if not t2 // 148 in dic_138:
                    dic_138[int(t2 // 148)] = [[each_ls[0], arg2[1], t1, t2]]
                else:
                    dic_138[int(t2 // 148)].append([each_ls[0], arg2[1], t1, t2])
    for d in [dic_135, dic_138]:
        for item in d.items():
            m = len(item[1])
            if m > 1:
                item[1].append('分界处')
                for i in range(m):
                    for j in range(i+1, m):
                        v1 = vel(item[1][i][1]-55, item[1][j][1]-55, item[1][i][2], item[1][j][2])
                        v2 = vel(item[1][i][1]-55, item[1][j][1]-55, item[1][i][3], item[1][j][3])
                        xQ = queue_length(item[1][i][3], item[1][i][2], item[1][i][1]-55, v1, v2)
                        item[1].append(xQ)
    return ls, [dic_135, dic_138]


def save_to_excel(ls, dic_ls, folder, fi):
    wb = Workbook()
    ws = wb.active
    ws.append(['', '停车前一时间点', '', '', '', '刚停车时刻', '', '', '', '启动时刻', '', '', '', '启动后一时间点', '', '', ''])
    ws.append(['VehNr', 't', 'WorldX', 'WorldY', 'vMS', 't', 'WorldX', 'WorldY', 'vMS', 't', 'WorldX', 'WorldY', 'vMS', 't', 'WorldX','WorldY', 'vMS', 't1\'', 't2\'', 'tg-t1', 't2-tg', '时间段1', '时间段2'])
    for li in ls:
        if li[1]:
            tmp = [li[0]]
            try:
                a = li[1]['首次0邻']
                tmp += a
            except KeyError:
                tmp += ['', '', '', '']
            tmp += li[1]['首次0']
            try:
                b = li[1]['最后0']
                tmp += b
            except KeyError:
                tmp += ['', '', '', '']
            try:
                c = li[1]['最后0邻']
                tmp += c
            except KeyError:
                tmp += ['', '', '', '']
            try:
                tmp.append(li[1]['t1’'])
                tmp.append(li[1]['t2‘'])
                tmp.append(li[1]['delta_t1'])
                tmp.append(li[1]['delta_t2'])
                tmp.append(li[1]['时间段1'])
                tmp.append(li[1]['时间段2'])
            except KeyError:
                pass
            ws.append(tmp)
        else:
            ws.append((li[0], ))

    with open(fi, 'r') as f:
        text = list(map(lambda x: re.sub(r'\n', '', x), f.readlines()))
    text = re.findall(r';all veh. types;all veh. types(.*)', '\n'.join(text), re.S)[0]
    text = text.split('\n')
    while '' in text:
        text.remove('')
    text = list(map(lambda x: x.split(';'), text))
    q_ls = list(map(lambda x: [eval(x[0])/148*3600,eval(x[0])/148*3600/eval(x[1])], text))
    for k, _a in enumerate(q_ls):
        ws[f'X{3+k}'] = _a[0]
        ws[f'Y{3+k}'] = _a[1]
    for i in range(97, 120):
        ws.column_dimensions[chr(i).upper()].alignment = Alignment(horizontal='centerContinuous', vertical='center', wrap_text=True)
    ws.merge_cells('B1:E1')
    ws.merge_cells('F1:I1')
    ws.merge_cells('J1:M1')
    ws.merge_cells('N1:Q1')
    for i in [2, 6, 10, 14]:
        ws.cell(row=2, column=i).fill = PatternFill(fill_type='solid', start_color='FF0000')
    for i in [3, 7, 11, 15]:
        ws.cell(row=2, column=i).fill = PatternFill(fill_type='solid', start_color='FFAFF0')
    for i in [4, 8, 12, 16]:
        ws.cell(row=2, column=i).fill = PatternFill(fill_type='solid', start_color='FFAFF0')
    for i in [5, 9, 13, 17]:
        ws.cell(row=2, column=i).fill = PatternFill(fill_type='solid', start_color='FFFF00')
    new_ws = wb.create_sheet('最大排队计算')
    new_ws.append(['周期/时间段'])
    combination_dic = {}     # 存放组合数字，留待按列写入表四
    for road, d in zip(['135车道', '138车道'], dic_ls):
        new_ws.append((road,))
        for item in d.items():
            print(item)
            if '分界处' in item[1]:
                ind = item[1].index('分界处')
                sort_ls = sorted(item[1][:ind], key=lambda x: x[2])
                new_ws.append([item[0]]+sum(sort_ls, []))
                new_ws.append(['']+item[1][ind+1:])
                if not item[0] in combination_dic:
                    combination_dic[item[0]] = item[1][ind + 1:]
                else:
                    combination_dic[item[0]] += item[1][ind + 1:]
            else:
                new_ws.append([item[0]]+sum(item[1], []))
    third_ws = wb.create_sheet('表3')
    third_ws.append(['周期/时间段'])
    T = set(dic_ls[0].keys()) | set(dic_ls[1].keys())
    # print(T)
    for t in T:
        d1, d2 = dic_ls
        if t in d1 and t in d2:
            value1 = d1[t]
            value2 = d2[t]
            if '分界处' in value1 and '分界处' in value2:
                ind1 = value1.index('分界处')
                sort_ls1 = sorted(value1[:ind1], key=lambda x: x[2])
                ind2 = value2.index('分界处')
                sort_ls2 = sorted(value2[:ind2], key=lambda x: x[2])
                third_ws.append([t]+sum(sort_ls1+[['']]+sort_ls2, []))
                third_ws.append(['']+value1[ind1+1:]+['']+value2[ind2+1:])
            elif '分界处' in value1:
                ind1 = value1.index('分界处')
                sort_ls1 = sorted(value1[:ind1], key=lambda x: x[2])
                third_ws.append([t]+sum(sort_ls1, []))
                third_ws.append(['']+value1[ind1+1:])
            elif '分界处' in value2:
                ind2 = value2.index('分界处')
                sort_ls2 = sorted(value2[:ind2], key=lambda x: x[2])
                third_ws.append([t]+sum(sort_ls2, []))
                third_ws.append(['']+value2[ind2+1:])
            else:
                third_ws.append([t]+sum(value1+[['']]+value2, []))
        elif t in d1:
            value = d1[t]
            if '分界处' in value:
                ind = value.index('分界处')
                sort_ls = sorted(value[:ind], key=lambda x: x[2])
                third_ws.append([t]+sum(sort_ls, []))
                third_ws.append(['']+value[ind+1:])
            else:
                third_ws.append([t]+sum(value, []))
        else:
            value = d2[t]
            if '分界处' in value:
                ind = value.index('分界处')
                sort_ls = sorted(value[:ind], key=lambda x: x[2])
                third_ws.append([t]+sum(sort_ls, []))
                third_ws.append(['']+value[ind+1:])
            else:
                third_ws.append([t]+sum(value, []))
                print(t, value)
    forth_ws = wb.create_sheet('表4')
    forth_ws.append(['周期/时间段'])
    for i in combination_dic:
        filter_ls = sorted(list(filter(lambda x: 0<=x<=300, combination_dic[i])))
        forth_ws.append([i, filter_ls[0]])
        for j in filter_ls[1:]:
            forth_ws.append(['', j])
    wb.save(folder + r'\过筛数据.xlsx')
    tkinter.messagebox.showwarning('提示', '筛选完毕')


def select_path1():
    path_ = filedialog.askopenfilename()
    path1.set(path_)


def select_path2():
    path_ = filedialog.askopenfilename()
    path2.set(path_)


def main():
    filename = entry1.get()
    folder = '\\'.join(filename.split('/')[:-1])
    tkinter.Label(root, text="开始筛选，请耐心等待").grid(row=5, column=0)
    try:
        rows, d = read_data(filename)
    except:
        tkinter.Label(root, text="\t\t").grid(row=5, column=0)
        tkinter.Label(root, text="文件格式出错，读取失败").grid(row=5, column=0)
        return
    try:
        l = choose_data(d)
    except:
        tkinter.Label(root, text="\t\t").grid(row=5, column=0)
        tkinter.Label(root, text="数据筛选出错").grid(row=5, column=0)
        return
    try:
        new_l, car_road = new_t(l)
    except:
        tkinter.Label(root, text="\t\t").grid(row=5, column=0)
        tkinter.Label(root, text="排队计算出错").grid(row=5, column=0)
        return
    try:
        save_to_excel(new_l, car_road, folder, entry2.get())
    except Exception as e:
        print(e)
        tkinter.Label(root, text="\t\t  ").grid(row=5, column=0)
        tkinter.Label(root, text="保存出错").grid(row=5, column=0)
        return
    num = 0
    for i in l:
        if i[1]:
            num += 1
    tkinter.Label(root, text="\t\t\t").grid(row=5, column=0)
    tkinter.Label(root, text="已保存筛选结果").grid(row=5, column=0)
    tkinter.Label(root, text="总共%d条数据，有效数据共计%d条" % (rows, num)).grid(row=6, column=0)


def thread_it(func, *args):
    t = threading.Thread(target=func, args=args)
    t.setDaemon(True)
    t.start()


if __name__ == '__main__':
    # d = read_data('hshl.fzp')
    # l = choose_data(d)
    # new_l, roads = new_t(l)
    # save_to_excel(new_l, roads)
    root = tkinter.Tk()
    root.title('筛选工具')
    root['width'] = 280
    root['height'] = 110
    path1 = tkinter.StringVar()
    path2 = tkinter.StringVar()
    tkinter.Label(root, text="\t\t\t").grid(row=0, column=0)
    tkinter.Label(root, text="选择数据文件后筛选").grid(row=1, column=0)
    entry1 = tkinter.Entry(root, textvariable=path1)
    entry1.grid(row=2, column=0)
    entry2 = tkinter.Entry(root, textvariable=path2)
    entry2.grid(row=3, column=0)
    tkinter.Button(root, text='选择fzp', command=select_path1).grid(row=2, column=1)
    tkinter.Button(root, text='选择mes', command=select_path2).grid(row=3, column=1)
    tkinter.Button(root, text='开始', command=lambda: thread_it(main,)).grid(row=4, column=0)
    tkinter.Label(root, text="\t\t\t").grid(row=5, column=0)
    tkinter.Label(root, text="\t\t\t").grid(row=6, column=0)
    root.mainloop()
